/**
 * 通用内容加载器
 * 支持多种数据来源：
 * 1. 直接字符串（数据库返回的内容）
 * 2. 项目内相对路径（如 /mock-documents/xxx.md）
 * 3. 外部 URL（如 MinIO 对象存储）
 * 4. Base64 编码内容
 */

/**
 * 内容来源类型检测
 * @param {string|object} source - 内容或内容配置
 * @returns {string} 内容类型：'direct' | 'path' | 'url' | 'base64'
 */
export function detectContentType(source) {
  if (!source) return 'empty';
  
  // 如果是对象，从对象中提取
  if (typeof source === 'object') {
    if (source.content) return 'direct';
    if (source.contentPath) return 'path';
    if (source.contentUrl) return 'url';
    if (source.contentBase64) return 'base64';
    return 'unknown';
  }
  
  // 如果是字符串
  if (typeof source === 'string') {
    // 检查是否是 URL（http:// 或 https://）
    if (/^https?:\/\//i.test(source)) {
      return 'url';
    }
    
    // 检查是否是 Base64（以 data: 开头）
    if (/^data:/.test(source)) {
      return 'base64';
    }
    
    // 检查是否是文件路径（以 / 或 ./ 开头，且以 .md 结尾）
    if (/^(\/|\.\/|\.\.\/|~\/).*\.md$/i.test(source)) {
      return 'path';
    }
    
    // 检查是否是相对路径（包含 / 但不是 URL）
    if (source.includes('/') && !source.includes('\n')) {
      return 'path';
    }
    
    // 默认为直接内容
    return 'direct';
  }
  
  return 'unknown';
}

/**
 * 从路径加载内容
 * @param {string} path - 文件路径
 * @returns {Promise<string>} 文件内容
 */
async function loadFromPath(path) {
  try {
    // 在 Vite 开发环境中，需要添加 ?raw 参数来获取原始文本内容
    // 否则 Vite 会返回处理后的 HTML
    const url = path.includes('?') ? path : `${path}?raw`;
    
    console.log(`📂 正在从路径加载: ${url}`);
    
    const response = await fetch(url, {
      headers: {
        'Accept': 'text/markdown, text/plain, */*'
      }
    });
    
    if (!response.ok) {
      throw new Error(`HTTP ${response.status}: ${response.statusText}`);
    }
    
    const content = await response.text();
    console.log(`✅ 加载成功，内容长度: ${content.length} 字符`);
    
    return content;
  } catch (error) {
    console.error(`❌ 加载文件失败: ${path}`, error);
    throw new Error(`无法加载文件: ${path}\n原因: ${error.message}`);
  }
}

/**
 * 从 URL 加载内容
 * @param {string} url - 远程 URL
 * @returns {Promise<string>} 文件内容
 */
async function loadFromUrl(url) {
  try {
    const response = await fetch(url, {
      headers: {
        'Accept': 'text/markdown, text/plain, */*'
      }
    });
    
    if (!response.ok) {
      throw new Error(`HTTP ${response.status}: ${response.statusText}`);
    }
    
    return await response.text();
  } catch (error) {
    console.error(`❌ 加载 URL 失败: ${url}`, error);
    throw new Error(`无法加载远程内容: ${url}\n原因: ${error.message}`);
  }
}

/**
 * 从 Base64 解码内容（支持 UTF-8 中文）
 * @param {string} base64 - Base64 编码的内容
 * @returns {string} 解码后的内容
 */
function loadFromBase64(base64) {
  try {
    // 移除 data:text/markdown;base64, 前缀（如果有）
    const base64Content = base64.replace(/^data:.*?;base64,/, '');
    
    // 正确的 UTF-8 解码方式（支持中文）
    // atob() 只能处理 ASCII，对于 UTF-8 需要额外处理
    const binaryString = atob(base64Content);
    
    // 方法 1: 使用 TextDecoder（推荐，现代浏览器支持）
    if (typeof TextDecoder !== 'undefined') {
      const bytes = new Uint8Array(binaryString.length);
      for (let i = 0; i < binaryString.length; i++) {
        bytes[i] = binaryString.charCodeAt(i);
      }
      const decoder = new TextDecoder('utf-8');
      return decoder.decode(bytes);
    }
    
    // 方法 2: 备用方案（兼容旧浏览器）
    return decodeURIComponent(escape(binaryString));
    
  } catch (error) {
    console.error('❌ Base64 解码失败', error);
    throw new Error(`Base64 解码失败: ${error.message}`);
  }
}

/**
 * 通用内容加载器
 * @param {string|object} source - 内容源
 * @param {object} options - 加载选项
 * @param {boolean} options.cache - 是否缓存（默认 true）
 * @param {number} options.timeout - 超时时间（毫秒，默认 5000）
 * @returns {Promise<string>} 加载的内容
 */
export async function loadContent(source, options = {}) {
  const { cache = true, timeout = 5000 } = options;
  
  // 检测内容类型
  const contentType = detectContentType(source);
  
  // 提取实际的内容源
  let actualSource = source;
  if (typeof source === 'object') {
    actualSource = source.content 
      || source.contentPath 
      || source.contentUrl 
      || source.contentBase64;
  }
  
  // 如果没有内容源，返回空
  if (!actualSource) {
    console.warn('⚠️ 内容源为空');
    return '';
  }
  
  // 根据类型加载内容
  try {
    let content;
    
    switch (contentType) {
      case 'direct':
        // 直接返回字符串内容（数据库返回的内容）
        content = actualSource;
        break;
        
      case 'path':
        // 从项目内路径加载（如 /mock-documents/xxx.md）
        console.log(`📂 从路径加载: ${actualSource}`);
        content = await Promise.race([
          loadFromPath(actualSource),
          new Promise((_, reject) => 
            setTimeout(() => reject(new Error('加载超时')), timeout)
          )
        ]);
        break;
        
      case 'url':
        // 从远程 URL 加载（如 MinIO 对象存储）
        console.log(`🌐 从 URL 加载: ${actualSource}`);
        content = await Promise.race([
          loadFromUrl(actualSource),
          new Promise((_, reject) => 
            setTimeout(() => reject(new Error('加载超时')), timeout)
          )
        ]);
        break;
        
      case 'base64':
        // 从 Base64 解码
        console.log(`🔓 从 Base64 解码`);
        content = loadFromBase64(actualSource);
        break;
        
      case 'empty':
        // 空内容
        content = '';
        break;
        
      default:
        // 未知类型，尝试作为直接内容处理
        console.warn(`⚠️ 未知内容类型: ${contentType}，作为直接内容处理`);
        content = actualSource;
    }
    
    // 缓存处理（可选）
    if (cache && typeof source === 'object' && source.id) {
      contentCache.set(source.id, content);
    }
    
    return content;
    
  } catch (error) {
    console.error('❌ 内容加载失败:', error);
    
    // 返回错误提示内容
    return `# ⚠️ 内容加载失败

## 错误信息
${error.message}

## 内容源
- 类型: ${contentType}
- 源: ${actualSource}

## 建议
- 检查文件路径是否正确
- 检查网络连接是否正常
- 检查内容格式是否有效
`;
  }
}

/**
 * 批量加载多个文档的内容
 * @param {Array} documents - 文档对象数组
 * @param {object} options - 加载选项
 * @returns {Promise<Array>} 加载了内容的文档数组
 */
export async function loadMultipleContents(documents, options = {}) {
  const { parallel = true, maxConcurrent = 5 } = options;
  
  if (!parallel) {
    // 串行加载
    const loadedDocs = [];
    for (const doc of documents) {
      const content = await loadContent(doc, options);
      loadedDocs.push({ ...doc, content });
    }
    return loadedDocs;
  }
  
  // 并行加载（限制并发数）
  const results = [];
  for (let i = 0; i < documents.length; i += maxConcurrent) {
    const batch = documents.slice(i, i + maxConcurrent);
    const batchResults = await Promise.all(
      batch.map(async (doc) => {
        const content = await loadContent(doc, options);
        return { ...doc, content };
      })
    );
    results.push(...batchResults);
  }
  
  return results;
}

/**
 * 内容缓存（简单的 Map 缓存）
 */
const contentCache = new Map();

/**
 * 清除缓存
 * @param {string|number} id - 文档 ID，不传则清除所有
 */
export function clearContentCache(id) {
  if (id) {
    contentCache.delete(id);
  } else {
    contentCache.clear();
  }
}

/**
 * 从缓存获取内容
 * @param {string|number} id - 文档 ID
 * @returns {string|null} 缓存的内容，不存在则返回 null
 */
export function getCachedContent(id) {
  return contentCache.get(id) || null;
}

/**
 * 预加载内容到缓存
 * @param {Array} documents - 文档对象数组
 */
export async function preloadContents(documents) {
  console.log(`📥 预加载 ${documents.length} 篇文档...`);
  const start = Date.now();
  
  await loadMultipleContents(documents, { cache: true, parallel: true });
  
  const duration = Date.now() - start;
  console.log(`✅ 预加载完成，耗时 ${duration}ms`);
}

/**
 * 智能内容加载器 - 自动判断并加载内容
 * @param {object} doc - 文档对象
 * @returns {Promise<object>} 包含内容的文档对象
 */
export async function smartLoadDocument(doc) {
  // 如果已经有内容，直接返回
  if (doc.content && typeof doc.content === 'string' && doc.content.trim()) {
    return doc;
  }
  
  // 检查缓存
  const cached = getCachedContent(doc.id);
  if (cached) {
    console.log(`💾 从缓存加载: ${doc.title}`);
    return { ...doc, content: cached };
  }
  
  // 动态加载内容
  console.log(`📥 动态加载: ${doc.title}`);
  const content = await loadContent(doc);
  
  return { ...doc, content };
}

/**
 * 开发模式下的调试工具
 */
if (typeof window !== 'undefined' && import.meta.env.DEV) {
  window.__contentLoader = {
    load: loadContent,
    detect: detectContentType,
    cache: contentCache,
    clearCache: clearContentCache,
    preload: preloadContents,
    smartLoad: smartLoadDocument
  };
  
  console.log('🛠️ 内容加载器调试工具已挂载到 window.__contentLoader');
}

